/**
 * @Subject.as
 *
 * @author sodaChen mail:sujun10@qq.com
 * @version 1.0
 * <br>Program Name:DoEasy
 * <br>Date:2016-9-7
 */
package com.asframe.pattern.observers
{
	import com.asframe.collections.maps.HashMap;
	import com.asframe.log.Log;
	import com.asframe.utils.VectorUtils;

	/**
	 * 观察者主题，这里是集中多种主题
	 * @author sodaChen
	 * #Date:2016-9-7
	 */
	public class NoticeSubjects implements INotifys
	{
		/** 存放观察者的集合 **/
		private var objectMap:HashMap;
		/** 存放监听函数的集合 **/
		private var linstenMap:HashMap;

		public function NoticeSubjects()
		{
			objectMap = new HashMap();
			linstenMap = new HashMap();
		}
		/**
		 * 添加一个观察者
		 * @param notice 观察主题消息
		 * @param observer 观察者
		 *
		 */
		public function addObserver(notice: *,observer:INoticeObserver):void
		{
			var observers:Vector.<INoticeObserver> = objectMap.get(notice);
			if(observers == null)
			{
				observers = new Vector.<INoticeObserver>();
				objectMap.put(notice,observers);
			}
			//查看是否重复
			if(observers.indexOf(observer) != -1)
			{
				Log.info(this,notice + "的" + observer + "进行重复添加了");
				return ;
			}

			observers.push(observer);
		}
		/**
		 * 添加一个观察者通知
		 * @param notice 通知名称
		 * @param linsten 通知监听函数
		 *
		 */
		public function addNotice(notice:*,linsten:Function):void
		{
			var linstens:Vector.<Function> = linstenMap.get(notice);
			if(linstens == null)
			{
				linstens = new Vector.<Function>();
				linstenMap.put(notice,linstens);
			}
			if(linstens.indexOf(linsten) != -1)
			{
				Log.info(this,notice + "的通知方法进行重复添加了");
				return ;
			}
			linstens.push(linsten);
		}

		/**
		 * 删除一个观察者通知
		 * @param notice 通知名称
		 * @param linsten 删除指定监听函数，为空则表示删除这个通知下的所有监听函数
		 *
		 */
		public function removeNotice(notice:*,linsten:Function):void
		{
			var linstens:Vector.<Function> = linstenMap.get(notice);
			if(linstens != null)
			{
				if(linsten == null)
					linstenMap.remove(notice);
				else
					VectorUtils.removeItem(linstens,linsten);
			}
		}
		/**
		 *
		 * @param notice
		 * @param observer
		 *
		 */
		public function removeObserver(notice: *,observer: INoticeObserver):void
		{
			var observers:Vector.<INoticeObserver> = objectMap.get(notice);
			if(observers == null || observers.length == 0)
			{
				Log.info(this,notice + "的" + observer + "已经不存在了，无法删除")
				return ;
			}
			VectorUtils.removeItem(observers,observer);
		}
		public function sendNotice(notice:*,params:Array):void
		{
			var observers:Vector.<INoticeObserver> = objectMap.get(notice);
			var linstens:Vector.<Function> = linstenMap.get(notice);
			if(observers != null && observers.length > 0)
			{
				for each (var observer:INoticeObserver in observers)
				{
					if(notice is String)
					{
						//如果有和通知一样名字的方法名，则直接反射，如果需要严禁怕误差，则需要使用Type来进行标签识别
						if(observer["hasOwnProperty"](notice))
						{
							observer[notice].apply(observer,params);
							continue ;
						}
					}
					//除字符串之外都是调用默认更新方法
					observer.update(notice,params);
				}
			}
			//函数注册的调用
			if(linstens != null && linstens.length > 0)
			{
				for each (var fun:Function in linstens)
				{
					fun.apply(null,params);
				}
			}
		}
		/**
		 * 发送一起通知
		 * @param notice 通知
		 * @param params 通知附带的参数
		 *
		 */
		public function send(notice:*,...args):void
		{
			sendNotice(notice,args);
		}
	}
}